<template>
	<view class="tui-datetime-picker">
		<view class="tui-header" :class="{ 'tui-show': isShow }">
			<view class="tui-picker-header" :class="{ 'tui-date-radius': radius }"
				:style="{ backgroundColor: headerBackground }" @touchmove.stop.prevent="stop" catchtouchmove="stop"
				v-if="false">
				<view class="tui-btn-picker" :style="{ color: cancelColor }" hover-class="tui-opacity"
					:hover-stay-time="150" @tap="hide">取消</view>
				<view class="tui-pickerdate__title" :style="{fontSize:titleSize+'rpx',color:titleColor}">{{title}}
				</view>
				<view class="tui-btn-picker" :style="{ color: color }" hover-class="tui-opacity" :hover-stay-time="150"
					@tap="btnFix">确定</view>
			</view>
			<view class="tui-date-header" :style="{ backgroundColor: unitBackground }" v-if="unitTop">
				<view class="tui-date-unit" v-if="type < 4 || type == 7 || type==8">年</view>
				<view class="tui-date-unit" v-if="type < 4 || type == 7 || type==8">月</view>
				<view class="tui-date-unit" v-if="type == 1 || type == 2 || type == 7 || type==8">日</view>
				<view class="tui-date-unit" v-if="type == 1 || type == 4 || type == 5 || type == 7 || type==8">时</view>
				<view class="tui-date-unit" v-if="(type == 1 || type > 3) && type!=8">分</view>
				<view class="tui-date-unit" v-if="type > 4 && type !=8">秒</view>
			</view>
			<view @touchstart.stop="pickerstart" class="tui-date__picker-body"
				:style="{ backgroundColor: bodyBackground,height:dataHeight+'rpx' }">
				<picker-view :value="value" @change="change" class="tui-picker-view" indicator-class="picker-box"
					style="top: -130rpx;" indicator-style="background: #EFF9E6;z-index: -1;">
					<picker-view-column class="years" v-if="!reset && (type < 4 || type == 7 || type==8)">
						<view class="tui-date__column-item" :class="{ 'tui-font-size_32': !unitTop && type == 7 }"
							v-for="(item, index) in years" :key="index">
							{{ item }}
							<text class="tui-date__unit-text" v-if="!unitTop">年</text>
						</view>
					</picker-view-column>
					<!-- <picker-view-column class="months" v-if="!reset && (type < 4 || type == 7 || type==8)">
						<view class="tui-date__column-item" :class="{ 'tui-font-size_32': !unitTop && type == 7 }"
							v-for="(item, index) in months" :key="index">
							{{ formatNum(item,days) }}
							<text class="tui-date__unit-text" v-if="!unitTop">月</text>
						</view>
					</picker-view-column> -->
					<picker-view-column class="days" v-if="!reset && (type == 1 || type == 2 || type == 7 || type==8)">
						<view class="tui-date__column-item" :class="{ 'tui-font-size_32': !unitTop && type == 7 }"
							v-for="(item, index) in new_days" :key="index">
							{{ item.day }}
							<view class="irreducible" v-if="item.timetable">不可约</view>
							<!-- <text class="tui-date__unit-text" v-if="!unitTop">日</text> -->
						</view>
					</picker-view-column>
					<picker-view-column class="hours"
						v-if="!reset && (type == 1 || type == 4 || type == 5 || type == 7 || type==8)">
						<view class="tui-date__column-item" :class="{ 'tui-font-size_32': !unitTop && type == 7 }"
							v-for="(item, index) in hours" :key="index">
							{{ formatNum(item) }}
							<text class="tui-date__unit-text" v-if="!unitTop">时</text>
						</view>
					</picker-view-column>
					<picker-view-column class="minutes"
						v-if="!reset && (type == 1 || type > 3)  && type!=8 && type != 10">
						<view class="tui-date__column-item" :class="{ 'tui-font-size_32': !unitTop && type == 7 }"
							v-for="(item, index) in minutes" :key="index">
							{{ formatNum(item) }}
							<text class="tui-date__unit-text" v-if="!unitTop">分</text>
						</view>
					</picker-view-column>
					<picker-view-column v-if="!reset && type > 4 && type!=8 && type != 10">
						<view class="tui-date__column-item" :class="{ 'tui-font-size_32': !unitTop && type == 7 }"
							v-for="(item, index) in seconds" :key="index">
							{{ formatNum(item) }}
							<text class="tui-date__unit-text" v-if="!unitTop">秒</text>
						</view>
					</picker-view-column>
					<picker-view-column class="choose_hours" v-if="!reset && type == 10">
						<view class="tui-date__column-item" v-for="(item, index) in choose_hours" :key="index">
							{{ item }}
							<text class="tui-date__unit-text">小时</text>
						</view>
					</picker-view-column>
				</picker-view>
			</view>
		</view>
	</view>
</template>

<script>
	import {
		timeFormat
	} from '@/uni_modules/uv-ui-tools/libs/function/index.js';
	import dayjs from "dayjs";
	const app = getApp();
	export default {
		options: {
			styleIsolation: 'shared'
		}, //解决/deep/不生效**
		name: 'tuiDatetime',
		emits: ['cancel', 'confirm'],
		props: {
			//1-日期+时间（年月日+时分） 2-日期(年月日) 3-日期(年月) 4-时间（时分） 5-时分秒 6-分秒 7-年月日 时分秒 8-年月日+小时
			type: {
				type: Number,
				default: 1
			},
			//年份区间
			startYear: {
				type: Number,
				default: 2023
			},
			//年份区间
			endYear: {
				type: Number,
				default: 2023
			},
			//显示标题
			title: {
				type: String,
				default: ''
			},
			//标题字体大小
			titleSize: {
				type: [Number, String],
				default: 34
			},
			//标题字体颜色
			titleColor: {
				type: String,
				default: '#333'
			},
			//"取消"字体颜色
			cancelColor: {
				type: String,
				default: '#888'
			},
			//"确定"字体颜色
			color: {
				type: String,
				default: '#5677fc'
			},
			//设置默认显示日期 2019-08-01 || 2019-08-01 17:01 || 2019/08/01
			setDateTime: {
				type: String,
				default: ''
			},
			//单位置顶
			unitTop: {
				type: Boolean,
				default: false
			},
			userId: {
				type: [Number, String],
				default: ''
			},
			//圆角设置
			radius: {
				type: Boolean,
				default: false
			},
			//头部背景色
			headerBackground: {
				type: String,
				default: '#fff'
			},
			//根据实际调整，不建议使用深颜色
			bodyBackground: {
				type: String,
				default: '#fff'
			},
			//单位置顶时，单位条背景色
			unitBackground: {
				type: String,
				default: '#fff'
			},
			height: {
				type: [Number, String],
				default: 240
			},
			//点击遮罩 是否可关闭
			maskClosable: {
				type: Boolean,
				default: true
			},
			choose_hours: {
				type: Array,
				default () {
					return [];
				}
			},

		},
		data() {
			return {
				isShow: !false,
				timetable: [],
				years: [],
				months: [],
				days: [],
				new_days: [],
				hours: [],
				minutes: [],
				seconds: [],
				year: 0,
				month: 0,
				day: 0,
				dayiy: 0,
				hour: 0,
				minute: 0,
				second: 0,
				startDate: '',
				endDate: '',
				value: [0, 0, 0, 0, 0, 0],
				reset: false,
				isEnd: true,
				dataHeight: 0,
			};
		},
		mounted() {

		},
		computed: {
			yearOrMonth() {
				return `${this.year}-${this.month}`;
			},
			propsChange() {
				return `${this.setDateTime}-${this.type}-${this.startYear}-${this.endYear}`;
			}
		},
		watch: {
			yearOrMonth() {
				this.setDays();
			},
			propsChange() {
				this.reset = true;
				setTimeout(() => {
					this.initData();
				}, 20);
			},
			height(newValue, old) {
				if (newValue <= 0) {
					this.dataHeight = newValue
					return
				}
				this.onTimetable(dayjs().format('YYYY')).then(() => {
					this.dataHeight = newValue
				})
			},
		},
		methods: {
			stop() {},
			formatNum: function(num) {
				return num < 10 ? '0' + num : num + '';
			},
			generateArray: function(start, end) {
				return Array.from(new Array(end + 1).keys()).slice(start);
			},
			getIndex: function(arr, val) {
				let index = arr.indexOf(val);
				return ~index ? index : 0;
			},
			getCharCount(str) {
				let regex = new RegExp('/', 'g');
				let result = str.match(regex);
				return !result ? 0 : result.length;
			},
			//日期时间处理
			initSelectValue() {
				let fdate = this.setDateTime.replace(/\-/g, '/');
				if (this.type == 3 && this.getCharCount(fdate) === 1) {
					fdate += '/01'
				}
				fdate = fdate && fdate.indexOf('/') == -1 ? `2020/01/01 ${fdate}` : fdate;
				let time = null;
				if (fdate) time = new Date(fdate);
				else time = new Date();
				this.year = time.getFullYear();
				this.month = time.getMonth() + 1;
				this.day = time.getDate();
				this.dayiy = this.month + '月' + this.formatNum(this.day) + '日';
				this.hour = time.getHours();
				this.minute = time.getMinutes();
				this.second = time.getSeconds();
			},
			initData() {
				this.initSelectValue();
				this.reset = false;
				switch (this.type) {
					case 1:
						this.value = [0, 0, 0, 0];
						this.setYears();
						this.setMonths();
						this.setDays();
						this.setNewDays()
						this.setHours();
						this.setMinutes();
						break;
					case 2:
						this.value = [0, 0, 0];
						this.setYears();
						this.setMonths();
						this.setDays();
						break;
					case 3:
						this.value = [0, 0];
						this.setYears();
						this.setMonths();
						break;
					case 4:
						this.value = [0, 0];
						this.setHours();
						this.setMinutes();
						break;
					case 5:
						this.value = [0, 0, 0];
						this.setHours();
						this.setMinutes();
						this.setSeconds();
						break;
					case 6:
						this.value = [0, 0];
						this.setMinutes();
						this.setSeconds();
						break;
					case 7:
						this.value = [0, 0, 0, 0, 0, 0];
						this.setYears();
						this.setMonths();
						this.setDays();
						this.setHours();
						this.setMinutes();
						this.setSeconds();
						break;
					case 8:
						this.value = [0, 0, 0, 0];
						this.setYears();
						this.setMonths();
						this.setDays();
						this.setHours();
						break;
					case 10:
						this.value = [0];
						break;
					default:
						break;
				}
			},
			setYears() {
				this.years = this.generateArray(this.startYear, this.endYear);
				setTimeout(() => {
					this.$set(this.value, 0, this.getIndex(this.years, this.year));
				}, 8);
			},
			setMonths() {
				this.months = this.generateArray(1, 12);
				return false
				setTimeout(() => {
					this.$set(this.value, 1, this.getIndex(this.months, this.month));
				}, 8);
			},
			setDays() {
				if (this.type == 3 || this.type == 4) return;
				let totalDays = new Date(this.year, this.month, 0).getDate();
				totalDays = !totalDays || totalDays < 1 ? 1 : totalDays
				this.days = this.generateArray(1, totalDays);
				return false
				setTimeout(() => {
					this.$set(this.value, 2, this.getIndex(this.days, this.day));
				}, 8);
			},

			setNewDays(year = 2023, istoday = true, sa) {
				let new_days = []
				let al = 0
				this.months.forEach((item, index) => {
					this.days.forEach((i, l) => {
						let yyyy = timeFormat(this.setDateTime, 'yyyy')
						let mm = timeFormat(this.setDateTime, 'mm')
						let dd = timeFormat(this.setDateTime, 'dd')
						if (year > yyyy) {
							new_days.push({
								day: this.formatNum(item) + '月' + this.formatNum(i) + '日',
								timetable: this.formatNum(item) == 12 && this.timetable.includes(
									this.formatNum(i))
							})
							this.new_days = new_days
							return
						}
						if (item >= mm && i >= dd) {
							new_days.push({
								day: this.formatNum(item) + '月' + this.formatNum(i) + '日',
								timetable: this.formatNum(item) == 12 && this.timetable.includes(
									this.formatNum(i))
							})
							if (!istoday && al == 0) {
								new_days = new_days.slice(1)
							}
							this.new_days = new_days
							al++
						}
					})
				})
				if (sa != 1) {
					setTimeout(() => {
						this.$set(this.value, 1, this.getIndexMinutes(this.new_days, this.dayiy));
					}, 8);
				}
			},
			getIndexMinutes: function(arr, val) {
				let resIndex = -1
				let dayIndex = 0
				arr.forEach((item, index) => {
					if (item.day == val && !item.timetable) {
						resIndex = index
					}
					if (item.day == val && item.timetable) {
						dayIndex = index < 0 ? index : 0
					}
				})
				return resIndex == -1 ? dayIndex : resIndex;
			},

			setHours(full = false) {
				let hh = timeFormat(this.setDateTime, 'hh')
				if (hh < 8 || hh > 22) {
					this.setNewDays(2023, false)
				}
				if (full) {
					hh = 7
				}
				this.hours = this.generateArray(hh > 7 ? hh : 7, 22);
				setTimeout(() => {
					let index = 0
					if (this.type == 8) {
						index = this.value.length - 1
					} else {
						index = this.type == 5 || this.type == 7 ? this.value.length - 3 : this.value.length - 2;
					}
					this.$set(this.value, index, this.getIndex(this.hours, this.hour));
				}, 8);
			},
			setMinutes(full = false) {
				let MM = timeFormat(this.setDateTime, 'MM')
				if (full) {
					MM = 0
				}
				this.minutes = this.generateArray(MM, 59);
				setTimeout(() => {
					let index = this.type > 4 ? this.value.length - 2 : this.value.length - 1;
					this.$set(this.value, index, this.getIndex(this.minutes, this.minute));
				}, 8);
			},
			setSeconds() {
				this.seconds = this.generateArray(0, 59);
				setTimeout(() => {
					this.$set(this.value, this.value.length - 1, this.getIndex(this.seconds, this.second));
				}, 8);
			},
			show() {
				setTimeout(() => {
					this.isShow = true;
				}, 50);
			},
			hide() {
				this.isShow = false;
				this.$emit('cancel', {});
			},
			maskClick() {
				if (!this.maskClosable) return;
				this.hide()
			},
			formatNumDate: function(num) {
				num = num.replace("月", "-")
				num = num.replace("日", "")
				return num;
			},
			onTimetable(yearNum, type = 0) {
				return new Promise((resolve, reject) => {
					app._post_form("/client/peng-timetable/select", {
							yearNum: yearNum,
							userId: this.userId
						},
						(res) => {
							let data = res.data
							this.timetable = []
							data.forEach(item => {
								this.timetable.push(item.closeDate.split(' ')[0].split('-')[2])
							})
							if (type == 0) {
								setTimeout(() => {
									this.initData();
								}, 20)
							}
							resolve(this.timetable);
						}, null, () => {
							// resolve();
						})
				})
			},
			change(e) {
				// if ((e.detail.value[0] + 1 > this.years.length ||
				// 		e.detail.value[1] + 1 > this.new_days.length ||
				// 		e.detail.value[2] + 1 > this.hours.length ||
				// 		e.detail.value[3] + 1 > this.minutes.length) && this.type == 1) return;
				if (!this.isShow) return;
				let value = this.value
				if (e.detail.value[2] != this.value[2] || e.detail.value[3] != this.value[3]) {
					this.value = e.detail.value;
					this.isEnd = true
					this.$emit('change', this.type == 10 ? {
						hours: this.choose_hours[this.value[0]],
						type: this.type
					} : {
						new_days: this.new_days[this.value[1]],
						year: this.year,
						dayiy: this.dayiy,
						hour: this.formatNum(this.hour),
						minute: this.formatNum(this.minute),
						type: this.type
					});
					return;
				}
				if (e.detail.value[0] != this.value[0] || e.detail.value[1] != this.value[1]) {
					// this.onTimetable(this.year, 1)
				}
				this.value = e.detail.value;
				switch (this.type) {
					case 1:
						this.year = this.years[this.value[0]];
						if (e.detail.value[2] == value[2] || e.detail.value[3] == value[3]) {
							this.setNewDays(this.year, true)
						}
						this.month = this.months[this.value[1]];
						this.dayiy = this.new_days[this.value[1]].day;
						this.day = this.days[this.value[2]];
						this.hour = this.hours[this.value[2]];
						this.minute = this.minutes[this.value[3]];
						this.setHours(this.value[1] > 0)
						this.setMinutes((this.value[1] > 0 || this.value[2] > 0))
						break;
					case 2:
						this.year = this.years[this.value[0]];
						this.month = this.months[this.value[1]];
						this.day = this.days[this.value[2]];
						break;
					case 3:
						this.year = this.years[this.value[0]];
						this.month = this.months[this.value[1]];
						break;
					case 4:
						this.hour = this.hours[this.value[0]];
						this.minute = this.minutes[this.value[1]];
						break;
					case 5:
						this.hour = this.hours[this.value[0]];
						this.minute = this.minutes[this.value[1]];
						this.second = this.seconds[this.value[2]];
						break;
					case 6:
						this.minute = this.minutes[this.value[0]];
						this.second = this.seconds[this.value[1]];
						break;
					case 7:
						this.year = this.years[this.value[0]];
						this.month = this.months[this.value[1]];
						this.day = this.days[this.value[2]];
						this.hour = this.hours[this.value[3]];
						this.minute = this.minutes[this.value[4]];
						this.second = this.seconds[this.value[5]];
						break;
					case 8:
						this.year = this.years[this.value[0]];
						this.month = this.months[this.value[1]];
						this.day = this.days[this.value[2]];
						this.hour = this.hours[this.value[3]];
						break;
					case 10:
						// console.log(e.detail.value[0]);
						// if (e.detail.value[0] == 4) {
						// 	this.value = [this.value[0] + 1];
						// }
						break;
					default:
						break;
				}
				this.isEnd = true
				this.$emit('change', this.type == 10 ? {
					hours: this.choose_hours[this.value[0]],
					type: this.type
				} : {
					new_days: this.new_days[this.value[1]],
					year: this.year,
					dayiy: this.dayiy,
					hour: this.formatNum(this.hour),
					minute: this.formatNum(this.minute),
					type: this.type
				});
			},
			selectResult() {
				let result = {};
				let year = this.year;
				let month = this.formatNum(this.month || 0);
				let day = this.formatNum(this.day || 0);
				let hour = this.formatNum(this.hour || 0);
				let minute = this.formatNum(this.minute || 0);
				let second = this.formatNum(this.second || 0);
				switch (this.type) {
					case 1:
						result = {
							year: year,
							month: month,
							day: day,
							hour: hour,
							minute: minute,
							result: `${year}-${month}-${day} ${hour}:${minute}`
						};
						break;
					case 2:
						result = {
							year: year,
							month: month,
							day: day,
							result: `${year}-${month}-${day}`
						};
						break;
					case 3:
						result = {
							year: year,
							month: month,
							result: `${year}-${month}`
						};
						break;
					case 4:
						result = {
							hour: hour,
							minute: minute,
							result: `${hour}:${minute}`
						};
						break;
					case 5:
						result = {
							hour: hour,
							minute: minute,
							second: second,
							result: `${hour}:${minute}:${second}`
						};
						break;
					case 6:
						result = {
							minute: minute,
							second: second,
							result: `${minute}:${second}`
						};
						break;
					case 7:
						result = {
							year: year,
							month: month,
							day: day,
							hour: hour,
							minute: minute,
							second: second,
							result: `${year}-${month}-${day} ${hour}:${minute}:${second}`
						};
						break;
					case 8:
						result = {
							year: year,
							month: month,
							day: day,
							hour: hour,
							result: `${year}-${month}-${day} ${hour}:00`
						};
						break;
					default:
						break;
				}
				this.$emit('confirm', result);
			},
			waitFix() {
				if (this.isEnd) {
					this.selectResult()
				} else {
					setTimeout(() => {
						this.waitFix()
					}, 50)
				}
			},
			btnFix() {
				setTimeout(() => {
					this.waitFix()
					this.hide();
				}, 80);
			},
			pickerstart() {
				this.isEnd = false
			}
		}
	};
</script>

<style lang="scss" scoped>
	.tui-datetime-picker {
		position: relative;
		// z-index: 996;
	}

	/deep/.picker-box {
		height: 80rpx;
		border: none;

		&:before {
			border: none;
		}

		&:after {
			border: none;
		}
	}

	.tui-picker-view {
		height: 100%;
		box-sizing: border-box;
		position: relative;

		.years,
		.months,
		.days,
		.hours,
		.minutes,
		.choose_hours {
			flex: none;
			width: 100%;
			z-index: 2;
		}

		.choose_hours {
			// width: 100rpx;
			box-sizing: border-box;
			padding-left: 24rpx;
			padding-right: 20rpx;

			.tui-date__column-item {
				padding-left: 24rpx;
				padding-right: 20rpx;
				justify-content: center;
			}

			/deep/.picker-box {
				border-radius: 20rpx;
			}
		}


		.years {
			width: 100rpx;
			padding-left: 24rpx;
			padding-right: 20rpx;

			.tui-date__column-item {
				padding-left: 24rpx;
				padding-right: 20rpx;
			}

			/deep/.picker-box {
				border-radius: 20rpx 0 0 20rpx;
			}
		}

		.days {
			width: 115rpx;
			padding-right: 134rpx;
		}

		.hours {
			width: 55rpx;
			padding-right: 24rpx;
		}

		.minutes {
			width: 55rpx;
			padding-right: 124rpx;

			/deep/.picker-box {
				border-radius: 0 20rpx 20rpx 0;
			}
		}
	}

	.tui-mask {
		position: fixed;
		z-index: 997;
		top: 0;
		right: 0;
		bottom: 0;
		left: 0;
		background-color: rgba(0, 0, 0, 0.6);
		visibility: hidden;
		opacity: 0;
		transition: all 0.3s ease-in-out;
	}

	.tui-mask-show {
		visibility: visible !important;
		opacity: 1 !important;
	}

	.tui-header {
		// z-index: 998;
		// position: fixed;
		// bottom: 0;
		// left: 0;
		width: 100%;
		transition: all 0.3s ease-in-out;
		transform: translateY(100%);
	}

	.tui-date-header {
		width: 100%;
		height: 52rpx;
		display: flex;
		align-items: center;
		justify-content: space-between;
		font-size: 28rpx;
		line-height: 26rpx;
		/* #ifdef MP */
		box-shadow: 0 15rpx 10rpx -15rpx #efefef;
		/* #endif */
		/* #ifndef MP */
		box-shadow: 0 15rpx 10rpx -15rpx #888;
		/* #endif */
		position: relative;
		z-index: 2;
	}

	.tui-date-unit {
		flex: 1;
		text-align: center;
	}

	.tui-show {
		transform: translateY(0);
	}

	.tui-picker-header {
		width: 100%;
		height: 90rpx;
		padding: 0 40rpx;
		display: flex;
		justify-content: space-between;
		align-items: center;
		box-sizing: border-box;
		font-size: 32rpx;
		position: relative;
	}

	.tui-date-radius {
		border-top-left-radius: 20rpx;
		border-top-right-radius: 20rpx;
		overflow: hidden;
	}

	.tui-picker-header::after {
		content: '';
		position: absolute;
		border-bottom: 1rpx solid #eaeef1;
		-webkit-transform: scaleY(0.5);
		transform: scaleY(0.5);
		bottom: 0;
		right: 0;
		left: 0;
	}

	.tui-date__picker-body {
		width: 100%;
		/* height: 520rpx; */
		overflow: hidden;
		-webkit-transition: all 0.2s linear;
		transition: all 0.2s linear;
		// margin-top: -80rpx;
	}

	.tui-date__column-item {
		display: flex;
		align-items: center;
		// justify-content: center;
		font-size: 30rpx;
		font-weight: 900;
		color: #282D2D;
		line-height: 40rpx;

		.irreducible {
			font-size: 20rpx;
			font-weight: 400;
			color: #FF4664;
			line-height: 36rpx;
			text-align: center;
			width: 80rpx;
			height: 36rpx;
			background: rgba(255, 70, 100, 0.1);
			border-radius: 8rpx;
			margin-left: 8rpx;
		}
	}

	.tui-font-size_32 {
		font-size: 32rpx !important;
	}

	.tui-date__unit-text {
		font-size: 24rpx !important;
	}

	.tui-btn-picker {
		padding: 16rpx;
		box-sizing: border-box;
		text-align: center;
		text-decoration: none;
		flex-shrink: 0;
		/* #ifdef H5 */
		cursor: pointer;
		/* #endif */
	}

	.tui-opacity {
		opacity: 0.5;
	}

	.tui-pickerdate__title {
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
		flex: 1;
		padding: 0 30rpx;
		box-sizing: border-box;
		text-align: center;
	}
</style>